package org.scalpel.common;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;

import org.xmlpull.v1.XmlPullParserException;
import org.xmlrpc.android.MethodCall;
import org.xmlrpc.android.XMLRPCServer;

import android.util.Log;

/**
 * 
 * @author Jerome Monceaux
 * 
 * XMLRPC server listening at port 49157 and allowing to call inputs using xmlrpc protocol. 
 */
public class RPCServer{
  
  HashMap<String, Object> fListObject = null;
  ServerSocket fSocket = null;
  
  // PORT : First Prime Number after in the "Dynamic, private or ephemeral" ports range: 49152 to 65535
  static int PORT = 49157;
  
  public RPCServer(HashMap<String, Object> listObject) {
    fListObject = listObject;
  }
  public void finish()
  {
    try {
      if( fSocket != null )
        fSocket.close();
      fSocket = null;
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
  public void listen() {
    XMLRPCServer server = null;
    try {
      fSocket = new ServerSocket(PORT);
      server = new XMLRPCServer();
    } catch (IOException e) {
      e.printStackTrace();
    }
    while (fSocket != null) {
        Socket client;
        MethodCall call = null;
        try {
          Log.i("ScalpelRPCServer","wait for client");
          client = fSocket.accept();
          Log.i("ScalpelRPCServer","got a client "+client.toString());
          call = server.readMethodCall(client);
          Log.i("ScalpelRPCServer","call read "+call.toString());
        } catch (IOException e) {
          e.printStackTrace();
          continue;
        } catch (XmlPullParserException e) {
          e.printStackTrace();
          continue;
        }
        String name = call.getMethodName();
        Log.i("ScalpelRPCServer","method name "+name);
        try {
          int iPoint = name.lastIndexOf('.');
          String objectName = name.substring(0, iPoint);
          String methName = name.substring(iPoint+1, name.length());

          HHObject hhobj = (HHObject)fListObject.get(objectName);
          if( hhobj == null )
          {
            Log.e("ScalpelRPCServer", "HHObject not found : " + objectName);
            continue;
          }
          
          try {
            server.respond(client, hhobj.setInput(methName, call.getParams()));
          } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
          } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
          } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
          }
          
        } catch (IOException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        }
    }
  }
}
